package com.appbee.core.client.htmleditor.toolbar;

import javax.inject.Inject;

import com.appbee.core.client.ui.ToggleButton;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.i18n.client.Constants;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.RichTextArea;
import com.google.gwt.user.client.ui.Widget;

/**
 * A sample toolbar for use with {@link RichTextArea}. It provides a simple UI
 * for all rich text formatting, dynamically displayed only for the available
 * functionality.
 */
public class RichTextToolbar extends Composite
{
	/**
	 * This {@link Constants} interface is used to make the toolbar's strings
	 * internationalizable.
	 */
	public interface Strings extends Constants
	{

		String bold();

		String italic();

		String underline();
	}

	/**
	 * We use an inner EventHandler class to avoid exposing event methods on the
	 * RichTextToolbar itself.
	 */
	private class EventHandler implements ClickHandler,
			KeyUpHandler
	{

		@Override
		public void onClick(ClickEvent event)
		{
			Widget sender = (Widget) event.getSource();

			if (sender == bold)
			{
				formater.toggleBold();
			}
			else if (sender == italic)
			{
				formater.toggleItalic();
			}
			else if (sender == underline)
			{
				formater.toggleUnderline();
			}
			else if (sender == richText)
			{
				// We use the RichTextArea's onKeyUp event to update the toolbar
				// status.
				// This will catch any cases where the user moves the cursur
				// using the
				// keyboard, or uses one of the browser's built-in keyboard
				// shortcuts.
				updateStatus();
			}
		}

		@Override
		public void onKeyUp(KeyUpEvent event)
		{
			Widget sender = (Widget) event.getSource();
			if (sender == richText)
			{
				// We use the RichTextArea's onKeyUp event to update the toolbar
				// status.
				// This will catch any cases where the user moves the cursur
				// using the
				// keyboard, or uses one of the browser's built-in keyboard
				// shortcuts.
				updateStatus();
			}
		}
	}

	private final Strings strings = (Strings) GWT.create(Strings.class);
	private final EventHandler handler = new EventHandler();

	private RichTextArea richText;
	private RichTextArea.Formatter formater;

	private final FlowPanel panel = new FlowPanel();
	private final ToggleButton bold;
	private ToggleButton italic;
	private ToggleButton underline;
	private final Button linkButton = new Button("Link");
	private final ListBox styleSelect = new ListBox();

	/**
	 * Creates a new toolbar that drives the given rich text area.
	 * 
	 * @param richText
	 *            the rich text area to be controlled
	 */
	@Inject
	public RichTextToolbar(IToolbarStyle style)
	{
		initWidget(panel);
		panel.add(styleSelect);
		panel.add(bold = createToggleButton(style.boldOn(),
											style.boldOff(),
											strings.bold()));
		panel.add(italic = createToggleButton(	style.italicOn(),
												style.italicOff(),
												strings.italic()));
		panel.add(underline = createToggleButton(style.underlineOn(),style.underlineOff(),strings.italic()));
		panel.add(linkButton);

		styleSelect.addItem("Insert", "insert");
		styleSelect.addItem("Page header", "h1");
		styleSelect.addItem("Sub header", "h2");
		styleSelect.addItem("Line", "hr");

		styleSelect.addChangeHandler(new ChangeHandler()
		{

			@Override
			public void onChange(ChangeEvent event)
			{
				String value = styleSelect.getValue(styleSelect
						.getSelectedIndex());
				if (value.equals("h1"))
					formater.insertHTML("<h1>Header</h1>");
				else if (value.equals("h2"))
					formater.insertHTML("<h2>Sub header</h2>");
				else if (value.equals("hr"))
					formater.insertHorizontalRule();
				styleSelect.setSelectedIndex(0);
			}
		});
		linkButton.addClickHandler(new ClickHandler()
		{

			@Override
			public void onClick(ClickEvent event)
			{
				String url = Window.prompt("Url", "");
				formater.createLink(url);
			}
		});
	}
	
	public void addToolbarWidget(Widget w)
	{
		panel.add(w);
	}
	

	public void setRichText(RichTextArea richText)
	{
		this.richText = richText;
		richText.addClickHandler(handler);
		richText.addKeyUpHandler(handler);
		this.formater = richText.getFormatter();
	}



	private ToggleButton createToggleButton(String onStyle,
											String offStyle,
											String tip)
	{
		ToggleButton tb = new ToggleButton(onStyle, offStyle);
		tb.addClickHandler(handler);
		tb.setTitle(tip);
		return tb;
	}

	/**
	 * Updates the status of all the stateful buttons.
	 */
	private void updateStatus()
	{
		bold.setValue(formater.isBold());
		italic.setValue(formater.isItalic());
		underline.setValue(formater.isUnderlined());
	}
}
